package mathExpEvaluator.model;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import mathExpEvaluator.model.exception.InvalidMathValueException;

public class MathValue {
	private Object value;

	private final String integerPattern = "\\d+";
	private final String doublePattern = "\\d+\\.\\d+";

	public boolean isInteger(String str) {
		Pattern pattern = Pattern.compile(integerPattern);
		Matcher matcher = pattern.matcher(str);
		if (matcher.matches()) {
			return true;
		} else
			return false;
	}

	public boolean isDouble(String str) {
		Pattern pattern = Pattern.compile(doublePattern);
		Matcher matcher = pattern.matcher(str);
		if (matcher.matches()) {
			return true;
		} else
			return false;
	}

	public MathValue(String v) throws InvalidMathValueException{
		if (isInteger(v)) {
			this.value = new Integer(v);
		}
		if (isDouble(v)) {
			this.value = new Double(v);
		}
	}

	public MathValue(Object value) {
		this.value = value;
	}

	public Object getValue() {
		return this.value;
	}

	public boolean equals(Object mValue) {
		if (mValue instanceof MathValue) {
			if (this.value.getClass().equals(
					((MathValue) mValue).getValue().getClass())) {
				if (value.getClass().equals(Integer.class)) {
					return this.integerValue() == ((MathValue) mValue)
							.integerValue();
				}
				if (value.getClass().equals(Double.class)) {
					return this.doubleValue() == ((MathValue) mValue)
							.doubleValue();
				}
			}
		}
		return false;
	}

	public MathValue operate(Operator op, List<MathValue> operants) {
		List<MathValue> ops = new ArrayList<MathValue>();
		ops.add(this);
		for (MathValue value : operants) {
			ops.add(value);
		}
		return op.apply(ops);
	}

	public int integerValue() {
		return ((Integer) value).intValue();
	}

	public double doubleValue() {
		return ((Double) value).doubleValue();
	}

	public boolean booleanValue() {
		return ((Boolean) value).booleanValue();
	}
	
	public String toString(){
		return this.value.toString();
	}

	// public static void main(String[] args) throws SecurityException,
	// IllegalArgumentException, NoSuchMethodException, InstantiationException,
	// IllegalAccessException, InvocationTargetException{
	// MathValue v1 = new MathValue("123");
	// MathValue v2 = new MathValue("132");
	// List<MathValue> ops = new ArrayList<MathValue>();
	// ops.add(v2);
	// System.out.println(v1.equals(v2));
	// System.out.println(v1.operate(new AddOperator(), ops).getValue());
	// }
}
